package jo.co.yui.alogcatviewer;

/*
 Core SWING Advanced Programming 
 By Kim Topley
 ISBN: 0 13 083292 8       
 Publisher: Prentice Hall  
 */

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Container;
import java.awt.Image;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.InputEvent;
import java.awt.event.KeyEvent;
import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStreamReader;

import javax.swing.AbstractAction;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextPane;
import javax.swing.KeyStroke;
import javax.swing.UIManager;
import javax.swing.event.CaretEvent;
import javax.swing.event.CaretListener;
import javax.swing.text.BadLocationException;
import javax.swing.text.DefaultStyledDocument;
import javax.swing.text.Style;
import javax.swing.text.StyleConstants;
import javax.swing.text.StyleContext;

public class AndroidLogcatViewer {
	static String lastdir = ".";
	private static StyleContext sc = new StyleContext();
	private final static DefaultStyledDocument doc = new DefaultStyledDocument(
			sc);
	// Create and add the constant width style
	private final static Style greenStyle = sc.addStyle("green", null);
	private final static Style redStyle = sc.addStyle("red", null);
	private final static Style orangeStyle = sc.addStyle("orange", null);
	private final static Style blueStyle = sc.addStyle("blue", null);
	private final static Style blackStyle = sc.addStyle("black", null);
	private static JFrame frame;
	private static JScrollPane scrollPane;
	static MyStatusBar statusBar = new MyStatusBar();
	
	public static void main(String[] args) {
		try {
			UIManager
					.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
		} catch (Exception evt) {
		}
		MyPanel pane = initComponent();
		
		JMenuBar menubar = initMenubar();
		
		frame = new JFrame("Android Logcat Viewer");
		frame.setJMenuBar(menubar);
		scrollPane = new JScrollPane(pane);
		
		Container contentPane = frame.getContentPane();
		contentPane.add(pane, BorderLayout.WEST);
		contentPane.add(pane.getScrollPane(), BorderLayout.CENTER);
		
	    contentPane.add(statusBar, BorderLayout.SOUTH);
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frame.setSize(900, 500);
		frame.setVisible(true);
		
	}

	public static void refresh(File file) {
		try {
			doc.remove(0, doc.getLength());
		} catch (BadLocationException e) {
			e.printStackTrace();
		}
		loadFile(file, doc);
	}

	private static JMenuBar initMenubar() {

		JMenuBar menuBar = new JMenuBar();
		JMenu menu = new JMenu("File");
		menuBar.add(menu);
		JMenuItem menuItem = new JMenuItem("Open File...");
		KeyStroke ctrlP = KeyStroke.getKeyStroke(KeyEvent.VK_O,
				InputEvent.CTRL_MASK);
		menuItem.setAccelerator(ctrlP);
		menuItem.addActionListener(new OpenFileAction());
		menu.add(menuItem);

		return menuBar;
	}

	private static MyPanel initComponent() {
		// Create the StyleContext, the document and the pane
		StyleConstants.setForeground(greenStyle, new Color(0, 100, 0));
		StyleConstants.setForeground(redStyle, new Color(255, 0, 0));
		StyleConstants.setForeground(orangeStyle, new Color(218, 165, 032));
		StyleConstants.setForeground(blueStyle, new Color(065, 105, 255));
		StyleConstants.setForeground(blackStyle, Color.BLACK);
		
		StyleConstants.setFontFamily(greenStyle, "Courier New");
		StyleConstants.setFontFamily(redStyle, "Courier New");
		StyleConstants.setFontFamily(orangeStyle, "Courier New");
		StyleConstants.setFontFamily(blueStyle	, "Courier New");
		StyleConstants.setFontFamily(blackStyle	, "Courier New");
		
//		JTextPane pane = new JTextPane(doc);
		MyPanel mypanel = new MyPanel(doc);
		final JTextPane pane = mypanel.getPane();
		pane.setEditable(true);
		pane.setFocusable(true);
		pane.setContentType("text/plain;charset=UTF-8");
		
		pane.addCaretListener(new CaretListener() {
			
			@Override
			public void caretUpdate(CaretEvent arg0) {
				System.out.println(arg0.toString());
				int line = MyPanel.getLineNumber(pane, arg0.getDot());
				int col = MyPanel.getColNumber(pane, arg0.getDot());
				statusBar.jLabel.setText(String.format("Line:%d Col:%d  ", line, col));
				
			}
		});
		return mypanel;
	}

	static void loadFile(final File file, final DefaultStyledDocument doc) {
		try {
			Thread thread = new Thread(new Runnable() {
				public void run() {
					loadLogFileIntoTextPane(file, doc);
				}
			});
			thread.start();
		} catch (Exception e) {
			System.out.println("Exception when constructing document: " + e);
			System.exit(1);
		}
	}

	private static void loadLogFileIntoTextPane(File file,
			DefaultStyledDocument doc) {
		try {
			if (file == null || !file.exists())
				return;
			lastdir = file.getPath();
			// Open the file that is the first
			// command line parameter
			FileInputStream fstream = new FileInputStream(file);
			// Get the object of DataInputStream
			DataInputStream in = new DataInputStream(fstream);
			BufferedReader br = new BufferedReader(new InputStreamReader(in, "UTF-8"));
			String strLine;
			// Read File Line By Line
			int offs = 0;
			while ((strLine = br.readLine()) != null) {
				// Print the content on the console
				// System.out.println(strLine);
				int length = strLine.length();
				char ch = ' ';
				if (length > 20) {
					ch = strLine.charAt(20);
				}
				strLine += "\n";
				if ('I' == ch) {
					doc.insertString(offs, strLine, greenStyle);
				} else if ('D' == ch) {
					doc.insertString(offs, strLine, blueStyle);
				} else if ('W' == ch) {
					doc.insertString(offs, strLine, orangeStyle);
				} else if ('E' == ch) {
					doc.insertString(offs, strLine, redStyle);
				} else {
					doc.insertString(offs, strLine, blackStyle);
				}
				offs += length + 1;
				// Close the input stream
			}
			fstream.close();
			in.close();
			br.close();
		} catch (Exception e) {// Catch exception if any
			System.err.println("Error: " + e.getMessage());
			e.printStackTrace();
		}
	}

}

class OpenFileAction extends AbstractAction {
	private static final long serialVersionUID = 1L;
	private static final Icon printIcon = new ImageIcon("Print.gif");
	OpenFileAction() {
		super("openfile", printIcon);
	}

	public void actionPerformed(ActionEvent actionEvent) {
		
		JFileChooser chooser = new JFileChooser();
		chooser.setCurrentDirectory(new File(AndroidLogcatViewer.lastdir));

		chooser.setFileFilter(new javax.swing.filechooser.FileFilter() {
			public boolean accept(File f) {
				return f.getName().toLowerCase().endsWith(".txt")
						|| f.isDirectory();
			}

			public String getDescription() {
				return "Text";
			}
		});

		int r = chooser.showOpenDialog(new JFrame());
		if (r == JFileChooser.APPROVE_OPTION) {
			File selectedFile = chooser.getSelectedFile();
			String name = selectedFile.getAbsolutePath();
			AndroidLogcatViewer.refresh(selectedFile);
			System.out.println(name);
		}
	}
}
